package com.love.marriage.cloud.service.impl;

import com.aliyun.dyplsapi20170525.models.BindAxbResponseBody;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.love.marriage.cloud.service.AliyunDyplsService;
import com.love.marriage.cloud.service.CallService;
import com.love.marriage.common.constants.RedisConstants;
import com.love.marriage.common.enums.DefaultAmountTypeEnum;
import com.love.marriage.common.enums.ResultEnum;
import com.love.marriage.common.exceptions.SystemException;
import com.love.marriage.common.redisKey.VirtualNumberKey;
import com.love.marriage.common.vo.SecurityUser;
import com.love.marriage.defaultAmountConfig.service.DefaultAmountConfigService;
import com.love.marriage.defaultAmountConfig.vo.DefaultAmountConfigVo;
import com.love.marriage.userBalanceInfo.service.UserBalanceInfoService;
import com.love.marriage.userBalanceInfo.vo.UserBalanceInfoVo;
import com.love.marriage.userInfo.entity.UserInfo;
import com.love.marriage.userInfo.service.UserInfoService;
import com.love.marriage.userInfo.vo.UserInfoVo;
import com.love.marriage.utils.RedisUtils;
import com.love.marriage.utils.StringUtils;
import com.love.marriage.utils.UserUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class CallServiceImpl implements CallService {

    private final AliyunDyplsService aliyunDyplsService;

    private final UserInfoService userInfoService;

    private final UserBalanceInfoService userBalanceInfoService;

    private final DefaultAmountConfigService defaultAmountConfigService;

    private final RedisUtils redisUtils;

    @Override
    public String bindPhone(String phoneA, String phoneB) throws Exception {
        SecurityUser loginUser = UserUtils.getLoginUser();
        if (loginUser == null) {
            throw new SystemException(ResultEnum.USER_NO_LOGIN);
        }
        // 2024/10/27 校验用户
        LambdaQueryWrapper<UserInfo> query = Wrappers.<UserInfo>lambdaQuery()
                .eq(UserInfo::getPhone, phoneA)
                .eq(UserInfo::getDeleteFlag, 0);
        UserInfo dbUser = userInfoService.getOne(query);
        if (dbUser == null) {
            throw new SystemException(ResultEnum.USER_NOT_EXIST);
        }
        // 2024/10/27 校验余额
        UserBalanceInfoVo userBalanceInfoVo = userBalanceInfoService.queryUserBalanceInfoByUserId(dbUser.getId());
        DefaultAmountConfigVo defaultAmountConfigVo = defaultAmountConfigService.queryDefaultAmountConfigByCode(DefaultAmountTypeEnum.CALL_MIN_AMOUNT.getCode());
        if (userBalanceInfoVo == null || userBalanceInfoVo.getBalance().compareTo(defaultAmountConfigVo.getAmount()) < 0) {
            throw new SystemException(ResultEnum.USER_NO_ENOUGH_BALANCE.getCode(), ResultEnum.USER_NO_ENOUGH_BALANCE.getValue() + defaultAmountConfigVo.getAmount() + '元');
        }
        // 2024/10/27 校验是否绑定
        String virtualNumber = redisUtils.get(VirtualNumberKey.virtualNumberBindingPhoneKey, phoneA + ":" + phoneB);
        if (StringUtils.isNotBlank(virtualNumber)) {
            return virtualNumber;
        }
        List<String> vList = redisUtils.sGet(VirtualNumberKey.virtualNumberKey, String.class);
        if (vList == null || vList.isEmpty()) {
            throw new SystemException(ResultEnum.VIRTUAL_NUMBER_NOT_EXIST);
        }
        for (String vNo : vList) {
            String res = judgeVirtualNumber(phoneA, phoneB, vList.get(0));
            if (res != null && !"a".equals(res) && !"b".equals(res)) {
                // 绑定虚拟号码
                BindAxbResponseBody.BindAxbResponseBodySecretBindDTO bindAxbResponseBodySecretBindDTO = aliyunDyplsService.bindPhone(phoneA, phoneB, vNo);
                // 绑定信息到redis
                bindingRedis(phoneA, phoneB, vNo, bindAxbResponseBodySecretBindDTO.getSubsId());
                return vNo;
            }
        }
        for (String vNo : vList) {
            if ("a".equals(judgeVirtualNumber(phoneA, phoneB, vNo))) {
                String subsIds = redisUtils.get(VirtualNumberKey.virtualNumberBindingSubPhoneKey, phoneA + ":" + vNo);
                String[] split;
                if (subsIds != null) {
                    split = subsIds.split(":");
                } else {
                    continue;
                }
                // 解绑阿里云通话
                aliyunDyplsService.unBindPhone(null, split[0], vNo);
                // 解绑a
                unBindingRedis(phoneA, split[1], vNo, split[0]);
                // 替换号码
                BindAxbResponseBody.BindAxbResponseBodySecretBindDTO bindAxbResponseBodySecretBindDTO = aliyunDyplsService.bindPhone(phoneA, phoneB, vList.get(0));
                // 绑定信息到redis
                bindingRedis(phoneA, phoneB, vNo, bindAxbResponseBodySecretBindDTO.getSubsId());
                return vNo;
            }
        }
        throw new SystemException("500", "号码" + phoneB + "正在通话中");
    }

    public String judgeVirtualNumber(String phoneA, String phoneB, String virtual) throws Exception {
        String a = redisUtils.get(VirtualNumberKey.virtualNumberBindingAPhoneKey, phoneA + ":" + virtual);
        String b = redisUtils.get(VirtualNumberKey.virtualNumberBindingBPhoneKey, phoneB + ":" + virtual);
        if (StringUtils.isBlank(a) && StringUtils.isBlank(b)) {
            return virtual;
        } else {
            return StringUtils.isBlank(b) ? "a" : "b";
        }
    }

    @Override
    public String bindPhoneUserId(Long userIdA, Long userIdB) throws Exception {
        UserInfoVo aInfo = userInfoService.queryUserInfo(userIdA);
        if (aInfo == null || StringUtils.isBlank(aInfo.getPhone())) {
            throw new SystemException(ResultEnum.USER_NOT_PHONE.getCode(), ResultEnum.USER_NOT_PHONE.getValue() + "userIdA:" + userIdA);
        }
        UserInfoVo bInfo = userInfoService.queryUserInfo(userIdB);
        if (bInfo == null || StringUtils.isBlank(bInfo.getPhone())) {
            throw new SystemException(ResultEnum.USER_NOT_PHONE.getCode(), ResultEnum.USER_NOT_PHONE.getValue() + "userIdb:" + userIdB);
        }
        return bindPhone(aInfo.getPhone(), bInfo.getPhone());
    }

    public void bindingRedis(String phoneA, String phoneB, String vNo, String subsId) {
        // 绑定虚拟账号
        redisUtils.setEx(VirtualNumberKey.virtualNumberBindingPhoneKey, phoneA + ":" + phoneB, vNo, 5 * 60, TimeUnit.SECONDS);
        // 绑定a
        redisUtils.setEx(VirtualNumberKey.virtualNumberBindingAPhoneKey, phoneA + ":" + vNo, phoneB, 5 * 60, TimeUnit.SECONDS);
        // 绑定b
        redisUtils.setEx(VirtualNumberKey.virtualNumberBindingBPhoneKey, phoneB + ":" + vNo, phoneA, 5 * 60, TimeUnit.SECONDS);
        // 绑定虚拟账号和手机号
        redisUtils.setEx(VirtualNumberKey.virtualNumberBindingKey, phoneA + ":" + vNo + ":" + phoneB + ":" + subsId, subsId, 5 * 60, TimeUnit.SECONDS);
        // 绑定子subId
        redisUtils.setEx(VirtualNumberKey.virtualNumberBindingSubPhoneKey, phoneA + ":" + vNo, subsId + ":" + phoneB, 5 * 60, TimeUnit.SECONDS);
    }

    public void unBindingRedis(String phoneA, String secretNo, String phoneB, String subId) {
        redisUtils.delete(VirtualNumberKey.virtualNumberBindingKey.getPrefix()
                + RedisConstants.SEGMENTATION + phoneA
                + RedisConstants.SEGMENTATION + secretNo
                + RedisConstants.SEGMENTATION + phoneB
                + RedisConstants.SEGMENTATION + subId);  // 删除绑定关系
        redisUtils.delete(VirtualNumberKey.virtualNumberBindingSubPhoneKey.getPrefix()
                + RedisConstants.SEGMENTATION + phoneA
                + RedisConstants.SEGMENTATION + secretNo
                + RedisConstants.SEGMENTATION + phoneB);  // 删除绑定关系
        redisUtils.delete(VirtualNumberKey.virtualNumberBindingPhoneKey.getPrefix()
                + RedisConstants.SEGMENTATION + phoneA
                + RedisConstants.SEGMENTATION + phoneB);
        // 删除a绑定
        redisUtils.delete(VirtualNumberKey.virtualNumberBindingAPhoneKey.getPrefix()
                + RedisConstants.SEGMENTATION + phoneA
                + RedisConstants.SEGMENTATION + secretNo);
        // 删除b绑定
        redisUtils.delete(VirtualNumberKey.virtualNumberBindingBPhoneKey.getPrefix()
                + RedisConstants.SEGMENTATION + phoneB
                + RedisConstants.SEGMENTATION + secretNo);
    }
}
